﻿
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using Red.Controls.Depot.Dialogs;
using Red.Controls.Depot.ViewModels;
using Red.Core;

namespace Red.Controls.Depot
{
    /// <summary>
    /// </summary>
    public partial class DepotTree : UserControl
    {
        #region Data

        private readonly DepotTreeItemRoot _root = new DepotTreeItemRoot();

        #endregion Data

        #region Properties

        /// <summary>
        /// Gets/sets a root path to the depot and source control provider
        /// </summary>
        public DepotInfo Depot
        {
            get { return _root.Depot; }

            set
            {
                if ( _root.Depot != value )
                {
                    _root.Depot = value;
                }
            }
        }

        public IEnumerable<string> Favorites
        {
            get { return _root.Favorites; }

            set
            {
                if ( _root.Favorites != value )
                {
                    _root.Favorites = value;
                }
            }
        }

        public bool ShowAssetView
        {
            get { return _root.ShowAssetView; }
            set
            {
                if ( _root.ShowAssetView != value )
                {
                    _root.ShowAssetView = value;
                }
            }
        }

        public DepotTreeItem SelectedItem
        {
            get
            {
                return _tree.SelectedItem as DepotTreeItem;
            }
        }

        #endregion Properties

        #region C-tor

        public DepotTree()
        {
            InitializeComponent();
            DataContext = _root;
        }

        #endregion C-tor

        #region Public methods

        /// <summary>
        ///     <see cref="Red.Controls.RedTree.SelectByPath(System.String)"/>
        /// </summary> 
        public bool SelectByPath( string path )
        {
            return _tree.SelectByPath( path );
        }

        /// <summary>
        ///     <see cref="Red.Controls.RedTree.FindItemByPath(System.String)"/>
        /// </summary>
        public DepotTreeItem FindItemByPath( string path )
        {
            return (DepotTreeItem)_tree.FindItemByPath( path );
        }

        /// <summary>
        ///     <see cref="Red.Controls.RedTree.Refresh()"/>
        /// </summary> 
        public async Task Refresh()
        {
            await _tree.Refresh();
        }

        #endregion Public methods

        #region Event handlers

        private void RemoveFromFavorites_Executed( object sender, ExecutedRoutedEventArgs e )
        {
            var root = DataContext as DepotTreeItemRoot;
            if ( root == null ) return;

            var favItem = e.Parameter as DepotTreeItemFavorite;
            if ( favItem != null )
            {
                var favs = new List<string>( root.Favorites );
                favs.Remove( favItem.Path );
                root.Favorites = favs;
            }
        }

        private void AddToFavorites_Executed( object sender, ExecutedRoutedEventArgs e )
        {
            var root = DataContext as DepotTreeItemRoot;
            if ( root == null ) return;

            var dirItem = e.Parameter as DepotTreeItemDirectory;
            if ( dirItem != null )
            {
                var favs = new List<string>( root.Favorites );
                favs.Add( dirItem.Path );
                root.Favorites = favs;
            }
        }

        private void AddToFavorites_CanExecute( object sender, CanExecuteRoutedEventArgs e )
        {
            var dirItem = e.Parameter as DepotTreeItemDirectory;
            e.CanExecute = ( dirItem != null );
        }

        private void Submit_Executed( object sender, ExecutedRoutedEventArgs e )
        {
            var depotTreeItemChangelist = e.Parameter as DepotTreeItemChangelist;
            var changelistId = depotTreeItemChangelist.ChangelistId;
            var submitWindow = new SubmitWindow { Owner = Window.GetWindow( this ), Depot = Depot, ChangelistId = changelistId };
            submitWindow.ShowDialog();
        }

        private void Submit_CanExecute( object sender, CanExecuteRoutedEventArgs e )
        {
            var depotTreeItemChangelist = e.Parameter as DepotTreeItemChangelist;
            e.CanExecute = Depot != null && depotTreeItemChangelist.CanSubmit();
        }

        private void EditChangelist_Executed( object sender, ExecutedRoutedEventArgs e )
        {
            var depotTreeItemChangelist = e.Parameter as DepotTreeItemChangelist;
            var changelistId = depotTreeItemChangelist.ChangelistId;
            var editWindow = new EditChangelistWindow { Owner = Window.GetWindow( this ), Depot = Depot, ChangelistId = changelistId };
            editWindow.ShowDialog();
        }

        private void EditChangelist_CanExecute( object sender, CanExecuteRoutedEventArgs e )
        {
            var depotTreeItemChangelist = e.Parameter as DepotTreeItemChangelist;
            /* 
             * We can only edit changelists that can be submitted.
             * That means all changelists except the default changelist.
             */
            e.CanExecute = Depot != null && depotTreeItemChangelist.CanSubmit();
        }

        public void DeleteChangelist_Executed( object sender, ExecutedRoutedEventArgs e )
        {
            var depotTreeItemChangelist = e.Parameter as DepotTreeItemChangelist;
            Depot.SourceControl.DeleteChangelist( depotTreeItemChangelist.ChangelistId );
        }

        public void DeleteChangelist_CanExecute( object sender, CanExecuteRoutedEventArgs e )
        {            
            // We can only delete empty non-default changelists.
            var depotTreeItemChangelist = e.Parameter as DepotTreeItemChangelist;
            e.CanExecute = Depot != null && depotTreeItemChangelist.CanSubmit() && Depot.SourceControl.IsChangelistEmpty( depotTreeItemChangelist.ChangelistId );
        }

        #endregion Event handlers
    }
}
